package cn.seaboot.admin.mvc.response;

import cn.seaboot.admin.mvc.Problem;
import cn.seaboot.commons.file.MediaType;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.Nullable;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 如果 ControllerExceptionHandler 配置得不好的话，最终的处理逻辑会到这里
 *
 * @author Mr.css
 * @version 2020-12-15 16:45
 */
public class ApplicationHandlerExceptionResolver extends DefaultHandlerExceptionResolver {
    private final Logger logger = LoggerFactory.getLogger(ApplicationHandlerExceptionResolver.class);

    private final Feedback feedback = new FeedbackJson();


    @Override
    @Nullable
    protected ModelAndView doResolveException(
            @NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @Nullable Object handler, @NotNull Exception ex) {
        logger.debug("bad request!", ex);
        return super.doResolveException(request, response, handler, ex);
    }

    /**
     * {{@link DefaultHandlerExceptionResolver#handleBindException}}
     * Override this method, a error json is sent back to the client.
     *
     * @param request  current HTTP request
     * @param response current HTTP response
     * @param handler  the executed handler
     * @return a ModelAndView indicating the exception was handled
     * @author Mr.css
     */
    @Override
    protected @NotNull ModelAndView handleBindException(@NotNull BindException ex, @NotNull HttpServletRequest request,
                                                        @NotNull HttpServletResponse response, @Nullable Object handler) throws IOException {
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        response.setContentType(MediaType.APPLICATION_PROBLEM_JSON_UTF8_VALUE);

        Problem problem = feedback.handlerBindException(request, response, ex);

        FastJsonView view = new FastJsonView();
        view.ofProblem(problem);
        return new ModelAndView(view);
    }
}
